package com.example.clsj.service;

import cn.hutool.core.util.IdUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.sax.handler.RowHandler;
import com.example.clsj.anno.Loggable;
import com.example.clsj.domain.DataY;
import com.example.clsj.mapper.DataYMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
@RequiredArgsConstructor
public class HandleDataService {

    private final DataYMapper dataYMapper;

    private static final ThreadPoolExecutor ex = new ThreadPoolExecutor(10, 20, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(6000));

    /**
     * 将指定路径下的数据导入到数据库中
     *
     * @param inPath 数据文件的路径
     * @return 导入操作的状态信息
     */
    @Loggable
    public String importDataToSj(String inPath) {
        // 创建File对象，表示输入文件，同时移除路径中的双引号
        File inFile = new File(inPath.replaceAll("\"", ""));

        // 检查输入文件是否存在
        if (!inFile.exists()) {
            log.info("inPath does not exist: {}", inPath);
        }

        // 使用SAX方式读取Excel文件，并处理每行数据
        ExcelUtil.readBySax(inFile, -1, createRowHandler());

        return "success";
    }

    /**
     * 创建行处理程序
     * 此方法用于生成一个处理表格行数据的函数，主要包含数据解析和存储逻辑
     *
     * @return 返回一个lambda表达式，该表达式定义了如何处理每个表格行的数据
     */
    private RowHandler createRowHandler() {
        // 返回一个行处理程序，包含具体的处理逻辑
        return (sheetIndex, rowIndex, rowCells) -> {
            // 记录当前正在处理的行信息
            log.info("[{}] [{}] {}", sheetIndex, rowIndex, rowCells);
            // 检查是否是标题行（通过第一列内容判断），如果是则跳过处理
            if ("年".equals(rowCells.get(0))) {
                return;
            }
            // 初始化计数器，用于后续解析行数据时的索引
            int count = 0;
            // 创建一个数据对象，用于存储从Excel行中解析出的数据
            DataY dataY = new DataY();
            // 为数据对象生成一个唯一的标识符
            dataY.setId(IdUtil.fastSimpleUUID());
            // 解析并设置数据对象的各个属性
            dataY.setYearN(String.valueOf(rowCells.get(count++)));
            dataY.setMonthN(String.valueOf(rowCells.get(count++)));
            dataY.setBusinessDate(String.valueOf(rowCells.get(count++)));
            dataY.setProvincialCompanyName(String.valueOf(rowCells.get(count++)));
            dataY.setUpstreamCustomerName(String.valueOf(rowCells.get(count++)));
            dataY.setOriginalDownstreamCustName(String.valueOf(rowCells.get(count++)));
            dataY.setStandardDscnCustomerCode(String.valueOf(rowCells.get(count++)));
            dataY.setStandardDscnCustomerName(String.valueOf(rowCells.get(count++)));
            dataY.setStandardDscnCustomerCity(String.valueOf(rowCells.get(count++)));
            dataY.setStandardDscnHospitalType(String.valueOf(rowCells.get(count++)));
            dataY.setHospitalType(String.valueOf(rowCells.get(count++)));
            dataY.setDeliveryAddress(String.valueOf(rowCells.get(count++)));
            dataY.setStandardPdnProductCode(String.valueOf(rowCells.get(count++)));
            dataY.setStandardPdnCommonName(String.valueOf(rowCells.get(count++)));
            dataY.setStandardPdnSpecifications(String.valueOf(rowCells.get(count++)));
            dataY.setStandardPdnCommercialCode(String.valueOf(rowCells.get(count++)));
            dataY.setStandardQuantity(String.valueOf(rowCells.get(count++)));
            dataY.setMainMeasurementName(String.valueOf(rowCells.get(count++)));
            dataY.setUnitPrice(String.valueOf(rowCells.get(count++)));
            dataY.setAmountOfMoney(String.valueOf(rowCells.get(count++)));
            dataY.setOfficeName(String.valueOf(rowCells.get(count++)));
            dataY.setSalespersonJobId(String.valueOf(rowCells.get(count++)));
            dataY.setSalespersonName(String.valueOf(rowCells.get(count++)));
            dataY.setSecondarySalesTeamName(String.valueOf(rowCells.get(count++)));
            dataY.setUnitAssessmentPrice(String.valueOf(rowCells.get(count++)));
            dataY.setTotalAssessmentPrice(String.valueOf(rowCells.get(count++)));
            dataY.setCentralizedProcurement(String.valueOf(rowCells.get(count++)));

            // 如果队列大小超过5000，暂停一段时间以避免过载
            if (ex.getQueue().size() > 5000) {
                log.info("wait some times");
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    log.error(e.getMessage(), e);
                }
            }
            // 提交数据对象到线程池，执行插入数据库的操作
            ex.submit(() -> {
                dataYMapper.insertSelective(dataY);
            });
        };
    }

}
